package i2.application.fmw.dao.jpa;

import i2.application.fmw.dao.DAO;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;

@Repository("jpadao")
public abstract class JPADAO<E> implements DAO<E> {

	protected Logger logger = LoggerFactory.getLogger(getClass());
	private Class<E> entityClass;

	@PersistenceContext
	protected EntityManager entityManager;

	@SuppressWarnings("unchecked")
	public JPADAO() {
		Type type = getClass().getGenericSuperclass();
		logger.debug("genericSuperClass : {}",type);
		if (type instanceof ParameterizedType) {
			ParameterizedType genericSuperclass = (ParameterizedType) type;
			this.entityClass = (Class<E>) genericSuperclass.getActualTypeArguments()[0];
		} else {
			logger.error("genericSuperClass {} is not a ParameterizedType",type);
		}
	}

	@Override
	public void add(E entity) {
		logger.debug("add {}",entity);
		entityManager.persist(entity);
	}

	@Override
	public E update(E entity) {
		logger.debug("update {}",entity);
		return entityManager.merge(entity); 
	}

	@Override
	public void delete(E entity) {
		logger.debug("remove {}",entity);
		entity = entityManager.merge(entity); 
		entityManager.remove(entity); 
	}

	// ON FORCE LES ID EN TANT QUE INT !!!

	@Override
	public E findById(int id) {
		return entityManager.find(entityClass, id);
	}


	/* (non-Javadoc)
	 * @see i2.application.damfw.dao.DAO#findAll()
	 */
	@SuppressWarnings("unchecked")
	@Override
	public List<E> findAll() {
		List<E> entityList = null;
		Query query = entityManager.createQuery("SELECT a FROM "+ entityClass.getName() + " a");
		entityList = query.getResultList();
		logger.debug("findAll {}", entityList);
		return entityList;
	}

	public void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}

}